<?php namespace App\Admin\Access\OperationGroup;

use App\Core\Repository\Repository as BaseRepository;
use App\Admin\Access\Operation\Repository as OperationRepository;

class Repository extends BaseRepository {
    
    public function model(){
        return new Model();
    }
    
    //获取所有分组
	public static function getAllGroups(){
        static $groups = [];
        if(!$groups){
            $repository = new Repository();
            $repository->resetQuery()->getQuery()->orderBy('name', 'asc');
            $groups = $repository->all();
        }
        return clone $groups;
	}
    
    //获取所有操作
	public static function getAllOperations(){
        static $operations = [];
        if(!$operations){
            $operation = new OperationRepository();
            $operations = $operation->all('id as key', 'name', 'group_id');
        }
        return clone $operations;
	}
    
    //从数据源获取数据
    public static function getDatasFromSource($sourceRaw){
        static $datas = [];
        if(!isset($datas[$sourceRaw])){
            $sourceDataRaw = str_replace('\\\\', '|', $sourceRaw);
            $dataSource = json_decode($sourceDataRaw, true);
            $source  = str_replace('|', '\\', $dataSource['source']);
            $key  = $dataSource['key'];
            $name  = $dataSource['name'];
            $sourceArr = explode('@', $source);
            $sourceClass = $sourceArr[0];
            $sourceMethodParamArr = explode(':', $sourceArr[1]);
            $sourceMethod = $sourceMethodParamArr[0];
            $sourceParams = isset($sourceMethodParamArr[1]) ? explode(',', $sourceMethodParamArr[1]) : [];
            $sourceObject = new $sourceClass();
            $dataRaw = call_user_func_array([$sourceObject, $sourceMethod], $sourceParams);
            $data = [];
            foreach($dataRaw as $item){
                $data[] = (object)[
                    'key' => $item->{$key},
                    'name' => $item->{$name},
                ];
            }
            $datas[$sourceRaw] = $data;
        }
        return $datas[$sourceRaw];
    }
	
	//通过角色获取权限体系结构
	public function getByRoleWithOperations($role = false){
        //获取所有操作组
        $groups = self::getAllGroups();
        //过滤操作
        $operations = self::getAllOperations();
        if($role){
            $roleOperationIds = $role->getOperationIds();
            foreach($operations as $key => $operation){
                if(!in_array($operation->key, $roleOperationIds)){
                    unset($operations[$key]);
                }
            }
        }
        //操作分组
        $groupOfOperations = [];
        foreach($operations as $operation){
            $grouId = '_'.$operation->group_id;
            if(!isset($groupOfOperations[$grouId])){
                $groupOfOperations[$grouId] = [$operation];
            }else{
                $groupOfOperations[$grouId][] = $operation;
            }
        }
        //数据匹配
        foreach($groups as $key => $group){
            //操作
            if($group->type == '1'){
                if(isset($groupOfOperations['_'.$group->group_id])){
                    $group->operations = $groupOfOperations['_'.$group->group_id];
                }else{
                    $group->operations = [];
                }
                $groups[$key] = $group;
                continue;
            }
            //数据
            if($group->type == '2'){
                $datas = self::getDatasFromSource($group->data_source);
                if($role && $role->is_manager != '1'){
                    $userDatas = $role->getDataIdsByGroupId($group->group_id);
                    foreach($datas as $key => $item){
                        if(!in_array($item->key, $userDatas)){
                            unset($datas[$key]);
                        }
                    }
                }
                $group->operations = $datas;
                $groups[$key] = $group;
            }
        }
        //删除没有子项的分组
        foreach ($groups as $key => $value){
            if(count($value->operations) == 0){
                unset($groups[$key]);
            }
        }
        return $groups;
	}
}